#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// MeshManager.h : interface of the MeshManager class
//

#include <set>
#include "Mesh.h"
#include "Common.h"
#include "MeshEvent.h"



class MeshManager
{
private:
    
    typedef std::set<ref<Mesh> > MeshSet;
    typedef std::set<ref<MeshBuffer> > MeshBufferSet;

public:

    MeshManager();

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    ref<MeshBuffer> registerMeshBuffer(ref<MeshBuffer> mat);

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
    
    // Deletes all Meshes and MeshBuffers
    void clear();

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    // Return NULL ptr if Mesh does not exist
    MeshBuffer* getMeshBufferById(int id) const;
    MeshBuffer* getMeshBufferByName(const std::wstring& name) const;
    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    std::wstring generateMeshBufferName(const std::wstring& prefix) const;
    
    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    typedef MeshBufferSet::const_iterator MeshBufferIt;
    MeshBufferIt beginMeshBuffers() const;
    MeshBufferIt endMeshBuffers() const;
    size_t getMeshBufferCount() const;

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
    // This will be called by the Meshs that are registered with this 
    // manager when one of their parameters change. The manager, in turn,
    // will notifiy all its listeners

    //void notifyMeshAppearanceChanged(MeshEvent& event_);

private:

    MeshBufferSet m_meshBuffers;
    std::set<int> m_meshBufferIds;

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
    // MeshListeners stuff
public:

    void addMeshListener(MeshListener* listener);
    void removeMeshListener(MeshListener* listener);

private:

    // We use set<> to avoid duplicates
    typedef std::set<MeshListener*>::iterator ListenerIt;
    std::set<MeshListener *> m_listeners;
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
};

